home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / misc / update / tpasc302.cpt / TCL Update / New Tiny Edit Files / CEditDoc.p
Encoding:
Text File  |  1990-05-11  |  11.1 KB  |  462 lines

  1. {****************************************************}
  2. {}
  3. {        CEditDoc.p                                                                            }
  4. {}
  5. {        Document methods for a tiny editor.                                            }
  6. {}
  7. {        Copyright ⌐ 1989, Symantec Corporation.  All rights reserved.            }
  8. {}
  9. {****************************************************}
  10.  
  11.  
  12. unit CEditDoc;
  13.  
  14. interface
  15.  
  16.     uses
  17.         TCL, TinyEditIntf;
  18.  
  19. implementation
  20.  
  21.  
  22. {**}
  23. { * IEditDoc}
  24. { *}
  25. { *    This is your document's initialization method.}
  26. { *    If your document has its own instance variables, initialize}
  27. { *    them here.}
  28. { *}
  29. { *    The least you need to do is initialize the superclass.}
  30. { *}
  31. { **}
  32.  
  33.     procedure CEditDoc.IEditDoc (aSupervisor: CApplication; printable: Boolean);
  34.  
  35.     begin
  36.         IDocument(aSupervisor, printable);
  37.     end;
  38.  
  39.  
  40. {**}
  41. { * NewFile}
  42. { *}
  43. { *    When the user chooses New from the File menu, the CreateDocument}
  44. { *    method in your Application class will send a newly created document}
  45. { *    this message. This method needs to create a new window, ready to}
  46. { *    work on a new document.}
  47. { *}
  48. { *    Since this method and the OpenFile method share the code for creating}
  49. { *    the window, you should use an auxiliary window-building method.}
  50. { *}
  51. { **}
  52.  
  53.     procedure CEditDoc.NewFile;
  54.  
  55.         var
  56.             wTitle: Str255;                { Window title string                }
  57.             wCount: integer;                { Index number of new window    }
  58.             wNumber: Str255;                { Index number as a string        }
  59.  
  60.     begin
  61.         {*}
  62. {         **    BuildWindow is the method that}
  63. {         **    does the work of creating a window.}
  64. {         **    Its parameter should be the data that}
  65. {         **    you want to display in the window.}
  66. {         **    Since this is a new window, there's nothing}
  67. {         **    to display.}
  68. {         **}
  69. {         *}
  70.  
  71.         BuildWindow(nil);
  72.  
  73.         {*}
  74. {         **    Append an index number to the}
  75. {         **    default name of the window.}
  76. {         *}
  77.  
  78.         itsWindow.GetTitle(wTitle);
  79.         wCount := gDecorator.GetWCount;
  80.         NumToString(wCount, wNumber);
  81.         wTitle := concat(wTitle, ' ');
  82.         wTitle := concat(wTitle, wNumber);
  83.         itsWindow.SetTitle(wTitle);
  84.  
  85.         {*}
  86. {         **    Send the window a Select message to make}
  87. {         **    it the active window.}
  88. {         *}
  89.  
  90.         itsWindow.Select;
  91.     end;
  92.  
  93.  
  94. {**}
  95. { * OpenFile}
  96. { *}
  97. { *    When the user chooses Open╔ from the File menu, the OpenDocument}
  98. { *    method in your Application class will let the user choose a file}
  99. { *    and then send a newly created document this message. The information}
  100. { *    about the file is in the SFReply record.}
  101. { *}
  102. { *    In this method, you need to open the file and display its contents}
  103. { *    in a window. This method uses the auxiliary window-building method.}
  104. { *}
  105. { **}
  106.  
  107.     procedure CEditDoc.OpenFile (macSFReply: SFReply);
  108.  
  109.         var
  110.             theFile: CDataFile;
  111.             theData: Handle;
  112.             theName: Str255;
  113.             theError, temp: OSErr;
  114.  
  115.     begin
  116.         {*}
  117. {         ** Create a file and send it a SFSpecify}
  118. {         **    message to set up the name, volume, and}
  119. {         **    directory.}
  120. {         **}
  121. {         *}
  122.  
  123.         new(theFile);
  124.         theFile.IDataFile;
  125.         theFile.SFSpecify(macSFReply);
  126.  
  127.         {*}
  128. {         **    Be sure to set the instance variable}
  129. {         **    so other methods can use the file if they}
  130. {         **    need to. This is especially important if}
  131. {         **    you leave the file open in this method.}
  132. {         **    If you close the file after reading it, you}
  133. {         **    should be sure to set itsFile to nil.}
  134. {         **}
  135. {         *}
  136.  
  137.         itsFile := theFile;
  138.  
  139.         {*}
  140. {         **    Send the file an Open message to}
  141. {         **    open it. You can use the ReadSome or}
  142. {         **    ReadAll methods to get the contents of the file.}
  143. {         **}
  144. {         *}
  145.  
  146.         theError := theFile.Open(fsRdWrPerm);
  147.  
  148.         {*}
  149. {         **    Check to see if we were able to open}
  150. {         **    the file. Send the error handler}
  151. {         **    a CheckOSError message. If there was}
  152. {         **    an error, CheckOSError returns false}
  153. {         **    and reports the error in an alert.}
  154. {         **    The default error message displays the}
  155. {         **    error number.}
  156. {         **    You can use Estr resources to customize}
  157. {         **    the error message.}
  158. {         **}
  159. {         **    Note that we send ourselves a Free}
  160. {         **    message. Since we're not going to open,}
  161. {         **    we should get rid of the object.}
  162. {         *}
  163.  
  164.         if not gError.CheckOSError(theError) then
  165.             begin
  166.                 Free;
  167.                 Exit(OpenFile);
  168.             end;
  169.  
  170.         {*}
  171. {         **    Make sure that the memory request to read}
  172. {         **    the data from the file doesn't use up any}
  173. {         **    of our rainy day fund and that the GrowMemory}
  174. {         **    method (in the application) knows that it's OK}
  175. {         **    if we couldn't get enough memory.}
  176. {         **}
  177. {         *}
  178.  
  179.         gApplication.RequestMemory(FALSE, TRUE);
  180.         temp := theFile.ReadAll(theData);                    { ReadAll creates the handle         }
  181.         gApplication.RequestMemory(FALSE, FALSE);    { Reset canFail to FALSE for         }
  182.                                                             { default memory-error handling }
  183.  
  184.  
  185.         if (theData = nil) or (GetHandleSize(theData) > 10240) then
  186.             begin
  187.                 ParamText('The file is too big.', '', '', '');
  188.                 PositionDialog('ALRT', 128);
  189.                 InitCursor;
  190.                 temp := Alert(128, nil);
  191.  
  192.                 if theData <> nil then
  193.                     DisposHandle(theData);
  194.                 Free;                            { Don't leave this object around }
  195.                 Exit(OpenFile);
  196.             end;
  197.  
  198.  
  199.         BuildWindow(theData);
  200.  
  201.         {*}
  202. {         **    In your application, you'll probably store}
  203. {         **    the data in some form as an instance variable}
  204. {         **    in your document class. For this example, there's}
  205. {         **    no need to save it, so we'll get rid of it.}
  206. {         **}
  207. {         *}
  208.  
  209.         DisposHandle(theData);
  210.  
  211.         {*}
  212. {         **    In this implementation, we leave the file}
  213. {         **    open. You might want to close it after}
  214. {         **    you've read in all the data.}
  215. {         **}
  216. {         *}
  217.  
  218.         itsFile.GetName(theName);
  219.         itsWindow.SetTitle(theName);
  220.         itsWindow.Select;            { Don't forget to make the window active }
  221.     end;
  222.  
  223.  
  224.  
  225. {**}
  226. { * BuildWindow}
  227. { *}
  228. { *    This is the auxiliary window-building method that the}
  229. { *    NewFile and OpenFile methods use to create a window.}
  230. { *}
  231. { *    In this implementation, the argument is the data to display.}
  232. { *}
  233. { **}
  234.  
  235.     procedure CEditDoc.BuildWindow (theData: Handle);
  236.  
  237.         var
  238.             theScrollPane: CScrollPane;
  239.             theMainPane: CEditPane;
  240.             theWindow: CWindow;     { Altered by TCL Weaver 1.0 (5/9/90) }
  241.  
  242.     begin
  243.         {*}
  244. {         **    First create the window and initialize}
  245. {         **    it. The first argument is the resource ID}
  246. {         **    of the window. The second argument specifies}
  247. {         **    whether the window is a floating window.}
  248. {         **    The third argument is the window's enclosure; it}
  249. {         **    should always be gDesktop. The last argument is}
  250. {         **    the window's supervisor in the Chain of Command;}
  251. {         **    it should always be the Document object.}
  252. {         **}
  253. {         *}
  254.  
  255.         new(theWindow);             { Altered by TCL Weaver 1.0 (5/9/90) }
  256.         itsWindow := theWindow;
  257.         itsWindow.IWindow(WINDculture, FALSE, gDesktop, SELF);
  258.  
  259.         {*}
  260. {         **    After you create the window, you can use the}
  261. {         **    SetSizeRect message to set the window╒s maximum}
  262. {         **    and minimum size. Be sure to set the max & min}
  263. {         **    BEFORE you send a PlaceNewWindow message to the}
  264. {         **    decorator.}
  265. {         **}
  266. {         **     The default minimum is 100 by 100 pixels. The}
  267. {         **    default maximum is the bounds of GrayRgn (The}
  268. {         **    entire display area on all screens.)}
  269. {         **}
  270. {         *}
  271.  
  272.         new(theScrollPane);
  273.  
  274.         {*}
  275. {         **    You can initialize a scroll pane two ways:}
  276. {         **        1. You can specify all the values}
  277. {         **           right in your code, as follows.}
  278. {         **        2. You can create a ScPn resource and}
  279. {         **           initialize the pane from the information}
  280. {         **           in the resource.}
  281. {         **}
  282. {         *}
  283.  
  284.         theScrollPane.IScrollPane(itsWindow, SELF, 10, 10, 0, 0, sizELASTIC, sizELASTIC, TRUE, TRUE, TRUE);
  285.  
  286.         {*}
  287. {         **    The FitToEnclFrame method makes the}
  288. {         **    scroll pane be as large as its enclosure.}
  289. {         **    In this case, the enclosure is the window,}
  290. {         **    so the scroll pane will take up the entire}
  291. {         **    window.}
  292. {         **}
  293. {         *}
  294.  
  295.         theScrollPane.FitToEnclFrame(TRUE, TRUE);
  296.  
  297.  
  298.         {*}
  299. {         **    itsMainPane is the document's focus}
  300. {         **    of attention. Some of the standard}
  301. {         **    classes (particularly CPrinter) rely}
  302. {         **    on itsMainPane pointing to the main}
  303. {         **    pane of your window.}
  304. {         **}
  305. {         **    itsGopher specifies which object}
  306. {         **    should become the gopher when the document}
  307. {         **    is activated.  By default,}
  308. {         **    the document becomes the gopher. It╒s}
  309. {         **    likely that your main pane handles commands}
  310. {         **    so you╒ll almost want to set itsGopher}
  311. {         **    to point to the same object as itsMainPane.}
  312. {         **}
  313. {         **    Note that the main pane is the}
  314. {         **    panorama in the scroll pane and not}
  315. {         **    the scroll pane itself.}
  316. {         **}
  317. {         *}
  318.  
  319.         new(theMainPane);
  320.         itsMainPane := theMainPane;
  321.         itsGopher := theMainPane;
  322.  
  323.         {*}
  324. {         **    The IEditPane method automatically}
  325. {         **    fits the pane to the enclosure and}
  326. {         **    gives us a little margin.}
  327. {         **}
  328. {         *}
  329.  
  330.         theMainPane.IEditPane(theScrollPane, SELF);
  331.  
  332.         {*}
  333. {         **    Send the scroll pane an InstallPanorama}
  334. {         **    to associate our pane with the scroll pane.}
  335. {         **}
  336. {         *}
  337.  
  338.         theScrollPane.InstallPanorama(theMainPane);
  339.  
  340.         if theData <> nil then
  341.             theMainPane.SetTextHandle(theData);
  342.  
  343.         {*}
  344. {         **    The Decorator is a global object that takes care}
  345. {         **    of placing and sizing windows on the screen.}
  346. {         **    You don't have to use it.}
  347. {         **}
  348. {         *}
  349.  
  350.         gDecorator.PlaceNewWindow(itsWindow);
  351.     end;
  352.  
  353.  
  354.  
  355. {**}
  356. { * DoSave}
  357. { *}
  358. { *    This method handles what happens when the user chooses Save from the}
  359. { *    File menu. This method should return TRUE if the file save was successful.}
  360. { *    If there is no file associated with the document, you should send a}
  361. { *    DoSaveFileAs message.}
  362. { *}
  363. { **}
  364.  
  365.     function CEditDoc.DoSave: Boolean;
  366.  
  367.         var
  368.             theData: Handle;
  369.             temp: OSErr;
  370.  
  371.     begin
  372.         if itsFile = nil then
  373.             DoSave := DoSaveFileAs
  374.         else
  375.             begin
  376.                 theData := CEditText(itsMainPane).macTE^^.hText;
  377.                 temp := CDataFile(itsFile).WriteAll(theData);
  378.  
  379.                 dirty := FALSE;                    { Document is no longer dirty        }
  380.                 gBartender.DisableCmd(cmdSave);
  381.                 DoSave := TRUE;                    { Save was successful                }
  382.             end;
  383.     end;
  384.  
  385.  
  386. {**}
  387. { * DoSaveAs}
  388. { *}
  389. { *    This method handles what happens when the user chooses Save As╔ from}
  390. { *    File menu. The default DoCommand method for documents sends a DoSaveFileAs}
  391. { *    message which displays a standard put file dialog and sends this message.}
  392. { *    The SFReply record contains all the information about the file you're about}
  393. { *    to create.}
  394. { *}
  395. { **}
  396.  
  397.     function CEditDoc.DoSaveAs (macSFReply: SFReply): Boolean;
  398.  
  399.         var
  400.             temp: OSErr;
  401.             theFile: CFile;     { Altered by TCL Weaver 1.0 (5/9/90) }
  402.  
  403.     begin
  404.         {*}
  405. {         **    If there's a file associated with this document}
  406. {         **    already, close it. The Free method for files}
  407. {         **    sends a Close message to the file before releasing}
  408. {         **    its memory.}
  409. {         **}
  410. {         *}
  411.  
  412.         if itsFile <> nil then
  413.             itsFile.Free;
  414.  
  415.  
  416.         {*}
  417. {         **    Create a new file, and then save it normally.}
  418. {         **}
  419. {         *}
  420.  
  421.         new(CDataFile(theFile));        { Altered by TCL Weaver 1.0 (5/9/90) }
  422.         itsFile := theFile;
  423.         CDataFile(itsFile).IDataFile;
  424.         itsFile.SFSpecify(macSFReply);
  425.         temp := itsFile.CreateNew(gSignature, 'TEXT');
  426.         temp := itsFile.Open(fsRdWrPerm);
  427.  
  428.         itsWindow.SetTitle(macSFReply.fName);
  429.  
  430.         DoSaveAs := DoSave;
  431.     end;
  432.  
  433.  
  434. {**}
  435. { * DoRevert}
  436. { *}
  437. { *    User chose Revert to Saved.}
  438. { *}
  439. { *    Reset the EditPane's text to the text that is in the DataFile,}
  440. { *    clear the dirty flag, and disable the Save command.}
  441. { *}
  442. { **}
  443.  
  444.     procedure CEditDoc.DoRevert;
  445.  
  446.         var
  447.             temp: OSErr;
  448.             theData: Handle;
  449.  
  450.     begin
  451.         temp := CDataFile(itsFile).ReadAll(theData);
  452.  
  453.         CEditPane(itsMainPane).SetTextHandle(theData);
  454.  
  455.         DisposHandle(theData);
  456.  
  457.         dirty := FALSE;
  458.         gBartender.DisableCmd(cmdSave);
  459.     end;
  460.  
  461.  
  462. end.